---------------------------------------------
-- The TRUE one.
-- Combines everything into one giant abomination =D
---------------------------------------------

library IEEE;
library UNISIM;
use IEEE.STD_LOGIC_1164.ALL;
use UNISIM.Vcomponents.all;

entity THE_MAIN_THING is
	PORT (
		clk : in STD_LOGIC;
		
		-- UART input
		in1 : in STD_LOGIC_VECTOR(31 downto 0);
		in2 : in STD_LOGIC_VECTOR(31 downto 0);
		
		-- UART output
		res1 : out STD_LOGIC_VECTOR(31 downto 0);
		res2 : out STD_LOGIC_VECTOR(31 downto 0);
		
		-- Debuggin output for signals
		wb_stage_val : out STD_LOGIC_VECTOR(31 downto 0);
		wb_stage_dest : out STD_LOGIC_VECTOR(4 downto 0);
		
		exec_to_dm_alu : out STD_LOGIC_VECTOR(31 downto 0);
		branch_and : out STD_LOGIC;
		
		debug_stall_if : out STD_LOGIC;
		debug_pc_if : out STD_LOGIC_VECTOR(31 downto 0);
		
		debug_asshole : out STD_LOGIC_VECTOR(4 downto 0)
	);
end THE_MAIN_THING;

architecture Behavioral of THE_MAIN_THING is

-- IF out signals
signal IF_PC_OUT : STD_LOGIC_VECTOR(31 downto 0) := x"00000000";
signal IF_INS_OUT : STD_LOGIC_VECTOR(31 downto 0):= x"00000000";
signal IF_PC_COMBI_OUT : STD_LOGIC_VECTOR(31 downto 0) := x"00000000";

-- DEC out signals
signal DEC_invalid : STD_LOGIC := '0'; -- assert '1' when the instruction is undefined

signal DEC_ALU_op : STD_LOGIC_VECTOR(5 downto 0) := "000000";
signal DEC_ALU_src : STD_LOGIC := '0';
signal DEC_reg_dst : STD_LOGIC := '0';

signal DEC_mem_read : STD_LOGIC := '0';
signal DEC_mem_write : STD_LOGIC := '0';

signal DEC_mem_reg : STD_LOGIC := '0';
signal DEC_reg_write_en : STD_LOGIC := '0';

signal DEC_next_pc_out : STD_LOGIC_VECTOR(31 downto 0):= x"00000000";
signal DEC_data_outp1 : STD_LOGIC_VECTOR(31 downto 0):= x"00000000";
signal DEC_data_outp2 : STD_LOGIC_VECTOR(31 downto 0):= x"00000000";
signal DEC_immediate_offset : STD_LOGIC_VECTOR(31 downto 0):= x"00000000";
signal DEC_wb_dst1 : STD_LOGIC_VECTOR(4 downto 0) := "00000";
signal DEC_wb_dst2 : STD_LOGIC_VECTOR(4 downto 0) := "00000";

signal DEC_rs_index : STD_LOGIC_VECTOR(4 downto 0) := "00000";
signal DEC_rt_index : STD_LOGIC_VECTOR(4 downto 0) := "00000";

signal DEC_if_stall : STD_LOGIC := '0';
signal DEC_pc_stall : STD_LOGIC := '0';

signal DEC_is_branch_out : STD_LOGIC := '0';
signal DEC_branch_to_here : STD_LOGIC_VECTOR(31 downto 0) := x"00000000";

signal DEC_is_jump_out : STD_LOGIC := '0';
signal DEC_jump_to_here : STD_LOGIC_VECTOR(31 downto 0) := x"00000000";

signal DEC_if_flush : STD_LOGIC := '0';

-- EXEC signals
signal EXEC_MEM_READ_OUT : STD_LOGIC := '0';
signal EXEC_MEM_WRITE_OUT : STD_LOGIC := '0';
signal EXEC_MEM_TO_REG_OUT : STD_LOGIC := '0'; -- Is this a load word operation? 
signal EXEC_REG_WRITE_OUT : STD_LOGIC := '0';

signal EXEC_ALU_OUT : STD_LOGIC_VECTOR(31 downto 0):= x"00000000"; -- Output from the ALU
signal EXEC_WRITE_DATA_OUT : STD_LOGIC_VECTOR(31 downto 0):= x"00000000"; -- immediate or register value to be written to word
signal EXEC_REG_DEST_OUT : STD_LOGIC_VECTOR(4 downto 0):="00000"; -- Destination register for later phases

signal EXEC_STORE_SRC_OUT : STD_LOGIC_VECTOR(4 downto 0):="00000"; -- Contains index of the register which is to be stored in RAM

signal EXEC_REG_WRITEBACK_DEST : STD_LOGIC_VECTOR(4 downto 0):="00000";

-- DATA_MEM signals
signal DM_REG_WRITE_OUT : STD_LOGIC := '0';
signal DM_MEM_TO_REG_OUT : STD_LOGIC := '0';
	
signal DM_ALU_OUT : STD_LOGIC_VECTOR(31 downto 0):= x"00000000"; -- output from ALU directly
signal DM_MEMORY_OUT : STD_LOGIC_VECTOR(31 downto 0):= x"00000000"; -- output from memory unit, to be used for LW
	
signal DM_REG_DEST_OUT : STD_LOGIC_VECTOR(4 downto 0) := "00000";

-- WB signals
signal WB_VAL_WRITE_OUT : STD_LOGIC_VECTOR(31 downto 0):= x"00000000";
signal WB_REG_WRITE_OUT : STD_LOGIC := '0';

-- PC signals
signal PC_PC_OUT : STD_LOGIC_VECTOR(31 downto 0):= x"00000000";

component IF_UNIT is
	Port (
        CLK : in STD_LOGIC;

        PC : in STD_LOGIC_VECTOR(31 downto 0);
		  STALL_FROM_DECODE : in STD_LOGIC;
		  FLUSH_FROM_DECODE : in STD_LOGIC;
			
        PC_OUT : out STD_LOGIC_VECTOR(31 downto 0);
		  PC_COMBI_OUT : out STD_LOGIC_VECTOR(31 downto 0); 
        INS : out STD_LOGIC_VECTOR(31 downto 0)
        );
end component;

component DECODE_UNIT is
	PORT (
		clk : in STD_LOGIC;

		next_pc_in : in STD_LOGIC_VECTOR(31 downto 0);
		next_instruction : in STD_LOGIC_VECTOR(31 downto 0);
		
		wb_write_dst : in STD_LOGIC_VECTOR(4 downto 0);
		wb_write_data : in STD_LOGIC_VECTOR(31 downto 0);
		wb_write_en : in STD_LOGIC;

		-- For data hazards!
		mem_read_feedback : in STD_LOGIC; -- For data hazards. To check if there are data hazards
		rt_index_feedback : in STD_LOGIC_VECTOR(4 downto 0); -- To check if register for lw is equal to any one we are currently using
		--
		
		-- For branch hazards! (forwarding)
		ex_mem_is_reg_write : in STD_LOGIC; -- Is there something being written to a register, that is currently in the ex/mem register
		ex_mem_reg_write_index : in STD_LOGIC_VECTOR(4 downto 0); -- ^ What register index is this?
		ex_mem_reg_data : in STD_LOGIC_VECTOR(31 downto 0);
		--
		
		-- For branch hazards (stall) (caused by ...)
		id_ex_is_reg_write : in STD_LOGIC; -- Is there something being written to a register, that is currently in the ex/mem register
		id_ex_reg_write_index : in STD_LOGIC_VECTOR(4 downto 0); -- ^ What register index is this?
		--
		
		-- For branch hazards (stall) (caused by...)
		ex_mem_is_mem_read : in STD_LOGIC;
		ex_mem_mem_to_reg : in STD_LOGIC;

		invalid : out STD_LOGIC; -- assert '1' when the instruction is undefined

		ALU_op : out STD_LOGIC_VECTOR(5 downto 0);
		ALU_src : out STD_LOGIC;
		reg_dst : out STD_LOGIC;

		mem_read : out STD_LOGIC;
		mem_write : out STD_LOGIC;

		mem_reg : out STD_LOGIC;
		reg_write_en : out STD_LOGIC;

		next_pc_out : out STD_LOGIC_VECTOR(31 downto 0);
		data_outp1 : out STD_LOGIC_VECTOR(31 downto 0);
		data_outp2 : out STD_LOGIC_VECTOR(31 downto 0);
		immediate_offset : out STD_LOGIC_VECTOR(31 downto 0);
		wb_dst1 : out STD_LOGIC_VECTOR(4 downto 0);
		wb_dst2 : out STD_LOGIC_VECTOR(4 downto 0);
		
		-- Shifting branch handling into ID
		is_branch_out : out STD_LOGIC;
		branch_to_here : out STD_LOGIC_VECTOR(31 downto 0);

		-- Jump handling in ID
		is_jump_out : out STD_LOGIC;
		jump_to_here : out STD_LOGIC_VECTOR(31 downto 0);
		
		rs_index : out STD_LOGIC_VECTOR(4 downto 0); 
		rt_index : out STD_LOGIC_VECTOR(4 downto 0);
		
		if_stall : out STD_LOGIC;
		pc_stall : out STD_LOGIC;
		
		if_flush : out STD_LOGIC -- Controls whether in the next cylce, IF flushes or not. NOT a registered output!

	);
end component;

component EXECUTE_UNIT is
	PORT (
	
	CLK : in STD_LOGIC;
	
	----------- CONTROL SIGNALS-----------
		-- USED CONTROL SIGNALS
	REG_DEST_IN : in STD_LOGIC; -- Which of the 5-bits will represent the destination register? If 0, then 20 downto 16. If 1, then 25 downto 21
	ALU_SRC_IN : in STD_LOGIC; -- WHAT should OP2 hold? 1 for immedate/offset, and 0 REGFILE2_IN
	ALU_OP_IN : in STD_LOGIC_VECTOR(5 downto 0); -- operation for ALU OP
		-- "FLOW-THROUGH" control signals (just passed onto next layer without any processing)
	MEM_READ_IN : in STD_LOGIC;
	MEM_WRITE_IN : in STD_LOGIC;
	REG_WRITE_IN : in STD_LOGIC;
	MEM_TO_REG_IN : in STD_LOGIC;
	
		-- DATA SIGNALS
	CUR_PC_IN : in STD_LOGIC_VECTOR(31 downto 0); -- PC to be added in
	IMMEDIATE_IN : in STD_LOGIC_VECTOR(31 downto 0); -- Immediate or offset
	REGFILE1_IN : in STD_LOGIC_VECTOR(31 downto 0); -- output from register file
	REGFILE2_IN : in STD_LOGIC_VECTOR(31 downto 0); -- output from register file
	REGDEST1_IN : in STD_LOGIC_VECTOR(4 downto 0); -- Register destination 20 downto 16
	REGDEST2_IN : in STD_LOGIC_VECTOR(4 downto 0); -- Register destination 25 downto 21
	
	-- SIGNALS to handle data hazards
		-- To know what signals are provided by the register file, for comparison later on
	REGSRC1_IN : in STD_LOGIC_VECTOR(4 downto 0); -- for RS
	REGSRC2_IN : in STD_LOGIC_VECTOR(4 downto 0); -- for RT
	
		-- To know what earlier instructions modified, so we can take necessary steps to fix them
	EX_MEM_REG_DEST : in STD_LOGIC_VECTOR(4 downto 0); -- Destination address of an earlier instruction
	EX_MEM_REG_VAL : in STD_LOGIC_VECTOR(31 downto 0); -- Actual value of ALU, later down in the pipeline (earlier instruction in time)
	EX_MEM_REG_IS_WRITE : in STD_LOGIC; -- Is an earlier instruction (which has just completed the EX combinatorial stage) writing to registers?
	MEM_WB_REG_DEST : in STD_LOGIC_VECTOR(4 downto 0); 
	MEM_WB_REG_VAL : in STD_LOGIC_VECTOR(31 downto 0);
	MEM_WB_REG_IS_WRITE : in STD_LOGIC; -- Is an earlier instruction (which has just completed the MEM combinatorial stage) writing to registers?
	
	----------- OUTPUTS ----------- 
	MEM_READ_OUT : out STD_LOGIC;
	MEM_WRITE_OUT : out STD_LOGIC;
	MEM_TO_REG_OUT : out STD_LOGIC; -- Is this a load word operation? 
	REG_WRITE_OUT : out STD_LOGIC;
	
	ALU_OUT : out STD_LOGIC_VECTOR(31 downto 0); -- Output from the ALU
	WRITE_DATA_OUT : out STD_LOGIC_VECTOR(31 downto 0); -- immediate or register value to be written to word
	REG_DEST_OUT : out STD_LOGIC_VECTOR(4 downto 0); -- Destination register for later phases
	
	-- For MEM_MEM data hazards
	STORE_SOURCE : out STD_LOGIC_VECTOR(4 downto 0); -- RT for a LW operation
	
	-- For branch hazards [COMBINATORIAL OUTPUT!!!!!!!]
	REG_WRITEBACK_DEST : out STD_LOGIC_VECTOR(4 downto 0)
	
	);
end component;

component MEM_UNIT is
	PORT (
	
	CLK : in STD_LOGIC;
	
	--- CONTROL RELATED SIGNALS
		--- Used controls
	MEM_READ_IN : in STD_LOGIC;
	MEM_WRITE_IN : in STD_LOGIC;
		--- FLOW THROUGH CONTROL SIGNALS
	REG_WRITE_IN : in STD_LOGIC;
	MEM_TO_REG_IN : in STD_LOGIC;
	
	--- DATA RELATED SIGNALS
	ALU_IN : in STD_LOGIC_VECTOR(31 downto 0); -- Either the address for the memory (write or read) OR the data to be fedback in later stages
	WRITE_DATA : in STD_LOGIC_VECTOR(31 downto 0); -- Data to be written into the memory unit
	REG_DEST_IN : in STD_LOGIC_VECTOR(4 downto 0); -- Register destination flowing through
	
	--- FOR MEM_MEM HAZARDS
	MEM_WB_IS_READ_IN : in STD_LOGIC; -- If the previous instruction is a read
	MEM_WB_IS_WRITE_TO_REG_IN : in STD_LOGIC; -- If the previous instruction will write back to a register
	WRITE_DATA_SRC_IN : in STD_LOGIC_VECTOR(4 downto 0); -- Register index of where the value we are writing from 
	MEM_WB_READ_TO_IN : in STD_LOGIC_VECTOR(4 downto 0); -- Register index of the previous instruction's destination registers
	MEM_WB_DATA_READ_IN : in STD_LOGIC_VECTOR(31 downto 0); -- The forwarded value from the MEM/WB register
	
	--- FOR UART INPUT
	U_OP1_IN : in STD_LOGIC_VECTOR(31 downto 0);
	U_OP2_IN : in STD_LOGIC_VECTOR(31 downto 0);
	
	------------------------------------------------------------------------------------------------------------------------
	--- OUTPUT SIGNALS ---
	------------------------------------------------------------------------------------------------------------------------
	--- CONTROL RELATED OUTPUT SIGNALS
	PC_SRC : out STD_LOGIC; -- 1 if we are required to branch, 0 if no branch
	REG_WRITE_OUT : out STD_LOGIC;
	MEM_TO_REG_OUT : out STD_LOGIC;
	
	--- DATA RELATED SIGNALS
	ALU_OUT : out STD_LOGIC_VECTOR(31 downto 0); -- output from ALU directly
	MEMORY_OUT : out STD_LOGIC_VECTOR(31 downto 0); -- output from memory unit, to be used for LW
	
	--- 
	REG_DEST_OUT : out STD_LOGIC_VECTOR(4 downto 0);
		
	
	---------------------------------
	-- UART PORTS
	---------------------------------
	U_RES1_OUT : out STD_LOGIC_VECTOR(31 downto 0);
	U_RES2_OUT : out STD_LOGIC_VECTOR(31 downto 0)
	
	);
end component;

component WRITEBACK_UNIT is
	PORT(
	
	REG_WRITE_IN : in STD_LOGIC;
	MEM_TO_REG_IN : in STD_LOGIC;
	
	ALU_OUTPUT_IN : in STD_LOGIC_VECTOR(31 downto 0);
	DATA_MEM_IN : in STD_LOGIC_VECTOR(31 downto 0);
	
	VAL_WRITE_OUT : out STD_LOGIC_VECTOR(31 downto 0);
	REG_WRITE_OUT : out STD_LOGIC
	
	);

end component;

component PC_UNIT is

	PORT (
	CLK : in STD_LOGIC;
	
	PC_BRANCH_IN : in STD_LOGIC_VECTOR(31 downto 0); -- Input from branched position
	PC_SEQUENTIAL_IN : in STD_LOGIC_VECTOR(31 downto 0); -- the next PC, in sequtential order
	PC_IS_BRANCH_IN : in STD_LOGIC; -- was there a branch somewhere down the pipeline?
	PC_JUMP_IN : in STD_LOGIC_VECTOR(31 downto 0); -- jump full addr
	PC_IS_JUMP_IN : in STD_LOGIC; -- was there a jump?
	
	STALL_FROM_DECODE : in STD_LOGIC;
	
	PC_OUT : out STD_LOGIC_VECTOR(31 downto 0)
	);
	
end component;


begin

----------------------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------------------
-- IF UNIT
----------------------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------------------


	IF_GUY : IF_UNIT 
	Port MAP (
	CLK => CLK,

   PC => PC_PC_OUT,
	STALL_FROM_DECODE => DEC_IF_STALL,
	FLUSH_FROM_DECODE => DEC_IF_FLUSH,

   PC_OUT => IF_PC_OUT,
	PC_COMBI_OUT => IF_PC_COMBI_OUT,
   INS => IF_INS_OUT);

----------------------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------------------
-- DECODE UNIT
----------------------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------------------
	DECODE : DECODE_UNIT
	PORT MAP (
		clk => clk,

		next_pc_in => IF_PC_OUT,
		next_instruction => IF_INS_OUT,
		
		wb_write_dst => DM_REG_DEST_OUT,
		wb_write_data => WB_VAL_WRITE_OUT,
		wb_write_en => WB_REG_WRITE_OUT,
		
		mem_read_feedback => DEC_mem_read, -- Used to detect load-use hazards
		rt_index_feedback => DEC_rt_index, -- Used to detect load-use hazards

		-- For branch hazards!
		ex_mem_is_reg_write => EXEC_REG_WRITE_OUT, -- Indicates if we are writing to SOME regsiter later on...
		ex_mem_reg_write_index => EXEC_REG_DEST_OUT,
		ex_mem_reg_data => EXEC_ALU_OUT, -- If we are writing to a register, it must have come from the ALU

		-- For branch hazards (stall)
		id_ex_is_reg_write => DEC_reg_write_en,
		id_ex_reg_write_index => EXEC_REG_WRITEBACK_DEST,
		--

		ex_mem_is_mem_read => EXEC_MEM_READ_OUT,
		ex_mem_mem_to_reg => EXEC_MEM_TO_REG_OUT,

		invalid => DEC_invalid, -- assert '1' when the instruction is undefined

		ALU_op => DEC_ALU_op,
		ALU_src => DEC_ALU_src,
		reg_dst => DEC_reg_dst,

		mem_read => DEC_mem_read,
		mem_write => DEC_mem_write,

		mem_reg => DEC_mem_reg,
		reg_write_en => DEC_reg_write_en,
		
		is_branch_out => DEC_is_branch_out,
		branch_to_here => DEC_branch_to_here,

		is_jump_out => DEC_is_jump_out,
		jump_to_here => DEC_jump_to_here,

		next_pc_out => DEC_next_pc_out,
		data_outp1 => DEC_data_outp1,
		data_outp2 => DEC_data_outp2,
		immediate_offset => DEC_immediate_offset,
		wb_dst1 => DEC_wb_dst1,
		wb_dst2 => DEC_wb_dst2,
		
		rs_index => DEC_rs_index,
		rt_index => DEC_rt_index,
		
		if_stall => DEC_if_stall,
		pc_stall => DEC_pc_stall,
		
		IF_FLUSH => DEC_IF_FLUSH
	);


----------------------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------------------
-- EXEC UNIT
----------------------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------------------

	EXEC: EXECUTE_UNIT
	PORT MAP (
	
	CLK => CLK,
	
	----------- CONTROL SIGNALS-----------
		-- USED CONTROL SIGNALS
	REG_DEST_IN => DEC_reg_dst, -- Which of the 5-bits will represent the destination register? If 0, then 20 downto 16. If 1, then 25 downto 21
	ALU_SRC_IN => DEC_ALU_src, -- WHAT should OP2 hold? 1 for immedate/offset, and 0 REGFILE2_IN
	ALU_OP_IN => DEC_ALU_op, -- operation for ALU OP
		-- "FLOW-THROUGH" control signals (just passed onto next layer without any processing)
	MEM_READ_IN => DEC_mem_read,
	MEM_WRITE_IN => DEC_mem_write,
	REG_WRITE_IN => DEC_reg_write_en,
	MEM_TO_REG_IN => DEC_mem_reg,
	
	-- DATA SIGNALS
	CUR_PC_IN => DEC_next_pc_out, -- PC to be added in
	IMMEDIATE_IN  => DEC_immediate_offset,
	REGFILE1_IN  => DEC_data_outp1,
	REGFILE2_IN  => DEC_data_outp2,
	REGDEST1_IN => DEC_wb_dst1,
	REGDEST2_IN => DEC_wb_dst2,
	
	-- HAZARD handling signals
	REGSRC1_IN => DEC_rs_index,
	REGSRC2_IN => DEC_rt_index,
	
	EX_MEM_REG_DEST => EXEC_REG_DEST_OUT,
	EX_MEM_REG_VAL => EXEC_ALU_OUT,
	EX_MEM_REG_IS_WRITE => EXEC_REG_WRITE_OUT,
	MEM_WB_REG_DEST => DM_REG_DEST_OUT,
	MEM_WB_REG_VAL => WB_VAL_WRITE_OUT,
	MEM_WB_REG_IS_WRITE => DM_REG_WRITE_OUT,
	
	----------- OUTPUTS ----------- 
	MEM_READ_OUT => EXEC_MEM_READ_OUT,
	MEM_WRITE_OUT => EXEC_MEM_WRITE_OUT,
	MEM_TO_REG_OUT => EXEC_MEM_TO_REG_OUT,
	REG_WRITE_OUT => EXEC_REG_WRITE_OUT,
	
	ALU_OUT => EXEC_ALU_OUT,
	WRITE_DATA_OUT => EXEC_WRITE_DATA_OUT,
	REG_DEST_OUT => EXEC_REG_DEST_OUT,
	
	STORE_SOURCE => EXEC_STORE_SRC_OUT,
	
	-- For branch hazards [COMBINATORIAL OUTPUT!!!!!!!]
	REG_WRITEBACK_DEST => EXEC_REG_WRITEBACK_DEST
	
	);

----------------------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------------------
-- DATA_MEM UNIT
----------------------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------------------

	DATA : MEM_UNIT 
	PORT MAP(
	
	CLK => CLK,
	
	--- CONTROL RELATED SIGNALS
		--- Used controls
	MEM_READ_IN => EXEC_MEM_READ_OUT,
	MEM_WRITE_IN => EXEC_MEM_WRITE_OUT,
		--- FLOW THROUGH CONTROL SIGNALS
	REG_WRITE_IN => EXEC_REG_WRITE_OUT,
	MEM_TO_REG_IN => EXEC_MEM_TO_REG_OUT,
	
	--- DATA RELATED SIGNALS
	ALU_IN => EXEC_ALU_OUT,
	WRITE_DATA => EXEC_WRITE_DATA_OUT,
	REG_DEST_IN => EXEC_REG_DEST_OUT,
	
	--- FOR MEM_MEM HAZARDS
	MEM_WB_IS_READ_IN => DM_MEM_TO_REG_OUT, -- If the previous instruction is a read
	MEM_WB_IS_WRITE_TO_REG_IN => DM_REG_WRITE_OUT, -- If the previous instruction will write back to a register
	WRITE_DATA_SRC_IN => EXEC_STORE_SRC_OUT, -- Register index of where the value we are writing from 
	MEM_WB_READ_TO_IN => DM_REG_DEST_OUT, -- Register index of the previous instruction's destination registers
	MEM_WB_DATA_READ_IN => DM_MEMORY_OUT, -- The forwarded value from the MEM/WB register
	
	--- FOR UART INPUT
	U_OP1_IN => in1,
	U_OP2_IN => in2,
	
	------------------------------------------------------------------------------------------------------------------------
	--- OUTPUT SIGNALS ---
	------------------------------------------------------------------------------------------------------------------------
	--- CONTROL RELATED OUTPUT SIGNALS
	REG_WRITE_OUT => DM_REG_WRITE_OUT,
	MEM_TO_REG_OUT => DM_MEM_TO_REG_OUT,
	
	--- DATA RELATED SIGNALS
	ALU_OUT => DM_ALU_OUT,
	MEMORY_OUT => DM_MEMORY_OUT,
	
	--- 
	REG_DEST_OUT => DM_REG_DEST_OUT,
	
	
	---------------------------------
	-- UART PORTS
	---------------------------------
	U_RES1_OUT => RES1,
	U_RES2_OUT => RES2
	
	);
	
----------------------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------------------
-- WRITEBACK UNIT
----------------------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------------------
	
	WRITEBACK : WRITEBACK_UNIT 
	PORT MAP(
	
	REG_WRITE_IN => DM_REG_WRITE_OUT,
	MEM_TO_REG_IN => DM_MEM_TO_REG_OUT,
	
	ALU_OUTPUT_IN => DM_ALU_OUT,
	DATA_MEM_IN => DM_MEMORY_OUT,
	
	VAL_WRITE_OUT => WB_VAL_WRITE_OUT,
	REG_WRITE_OUT => WB_REG_WRITE_OUT
	
	);


----------------------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------------------
-- PC UNIT
----------------------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------------------

	PC : PC_UNIT 
	PORT MAP (
	CLK => CLK,
	
	PC_BRANCH_IN => DEC_branch_to_here, -- Input from branched position
	PC_SEQUENTIAL_IN => IF_PC_COMBI_OUT, -- the next PC, in sequtential order
	PC_IS_BRANCH_IN => DEC_is_branch_out, -- was there a branch somewhere down the pipeline?
	STALL_FROM_DECODE => DEC_PC_STALL,
	PC_IS_JUMP_IN => DEC_is_jump_out,
	PC_JUMP_IN => DEC_jump_to_here,
	
	PC_OUT => PC_PC_OUT
	);
	
-------
-- EXTRACTING DEBUG SIGNALS
-------
	wb_stage_val <= WB_VAL_WRITE_OUT;
	wb_stage_dest <= DM_REG_DEST_OUT;

	exec_to_dm_alu <= EXEC_ALU_OUT;
	branch_and <=  DEC_is_branch_out;

	debug_stall_if <= DEC_if_stall;
	debug_pc_if <= IF_INS_OUT;
	
	debug_asshole <= EXEC_REG_WRITEBACK_DEST;

end Behavioral;

